//
//  WDSQLiteManager.m
//  ArtPage
//
//  Created by 王笛 on 16/9/20.
//  Copyright © 2016年 diwang. All rights reserved.
//

#import "WDSQLiteManager.h"
#import "WDDictToModel.h"

static WDSQLiteManager *manager = nil;

@implementation WDSQLiteManager

+ (WDSQLiteManager *)manager
{
    //一次性代码
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        if(!manager){
            
            manager = [[self alloc] init];
            
            NSArray *libs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
            NSString *path = [libs[0] stringByAppendingPathComponent:@"Zhihjf.db"];
            manager.fmdb = [[FMDatabase alloc] initWithPath:path];
            
            if (![manager.fmdb open]) {
                manager = nil;
            }
            
        }
    });
    
    return manager;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        if (!manager) {
            manager = [super allocWithZone:zone];
            
            NSArray *libs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
            NSString *path = [libs[0] stringByAppendingPathComponent:@"Zhihjf.db"];
            manager.fmdb = [[FMDatabase alloc] initWithPath:path];
        }
    });
    
    return manager;
}

#pragma mark - <<<<<<<<<<<<<<< 创建表 >>>>>>>>>>>>>>>
- (void)creatTable:(NSString *)tableName WithPrimaryKey:(NSArray *)primaryKey
{
    if([self isOpenDB])
    {
        NSMutableString *table = [NSMutableString stringWithFormat:@"create table if not exists %@(", tableName];
        
        int count = 0;
        
        NSArray *keyTypes = [WDDictToModel propertysToArray:tableName];
        for(NSString *keyType in keyTypes)
        {
            count++;
            [table appendString:keyType];
            
            [table appendString:@", "];
        }
        
        NSString *primarykeys = [[NSString alloc]init];
        //拼接主键
        for (NSString *pkey in primaryKey) {
            primarykeys = [primarykeys stringByAppendingString:[NSString stringWithFormat:@"%@,",pkey]];
        }
        
        if (primaryKey != nil) {
            [table appendString:[NSString stringWithFormat:@"primary key(%@))",[primarykeys substringToIndex:primarykeys.length - 1]]];
        }else{
            
            [table appendString:@"primaryId integer primary key autoincrement)"];
        }
        
        [manager.fmdb executeUpdate:table];
    }
}

#pragma mark - <<<<<<<<<<<<<<< 更新数据 >>>>>>>>>>>>>>>
- (void)updateWithTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues
{
    if([self isOpenDB])
    {
        
        for(NSString *key in [keyValues allKeys])
        {
            NSMutableString *table = [NSMutableString stringWithFormat:@"update %@ set %@ = ?", tableName, key];
            
            [manager.fmdb executeUpdate:table, keyValues[key]];
        }
    }
}

- (void)updateWithTable:(NSString *)tableName andModel:(NSObject *)model
{
    
    NSDictionary *keyValues = [self modelToDictWithModel:model];
    
    [self updateWithTable:tableName setKeyValues:keyValues];
}

- (void)updateWithTable:(NSString *)tableName setKeyValues:(NSDictionary *)keyValues whereCondition:(NSDictionary *)condition
{
    
    if([self isOpenDB])
    {
        
        for(NSString *key in [keyValues allKeys])
        {
            NSMutableString *table = [NSMutableString stringWithFormat:@"update %@ set %@ = ? where %@ = ?;", tableName, key, [condition allKeys][0]];
            
            [manager.fmdb executeUpdate:table, keyValues[key], condition[[condition allKeys][0]]];
        }
    }
}


#pragma mark - <<<<<<<<<<<<<<< 插入数据 >>>>>>>>>>>>>>>
- (void)insertWithKeyValues:(NSDictionary *)keyValues toTable:(NSString *)tableName
{
    if ([self isOpenDB]) {
        
        NSMutableString *table = [NSMutableString stringWithFormat:@"insert into %@(", tableName];
        
        NSArray *keys = [keyValues allKeys];
        NSArray *values = [keyValues allValues];
        
        int count = 0;
        
        for(NSString *key in keys)
        {
            [table appendString:key];
            count++;
            if(count != [keys count]){
                
                [table appendString:@","];
            }
        }
        
        [table appendString:@") values("];
        for(int i = 0; i < [keys count] - 1; i++){
            
            [table appendString:@"?,"];
        }
        
        [table appendString:@"?)"];
        
        [manager.fmdb executeUpdate:table withArgumentsInArray:values];
    }
}

- (void)insertWithTable:(NSString *)tableName andModel:(NSObject *)model
{
    
    NSDictionary *keyValues = [self modelToDictWithModel:model];
    
    [self insertWithKeyValues:keyValues toTable:tableName];
}

- (void)insertWithDictArr:(NSArray *)dictArr toTable:(NSString *)tableName
{
    NSArray *models = [WDDictToModel dictToModelWithModel:tableName andDict:dictArr];
    return [self insertWithTable:tableName andModelArr:models];
}

- (void)insertWithTable:(NSString *)tableName andModelArr:(NSArray *)modelArr
{
    for (id model in modelArr) {
        
        [self insertWithTable:tableName andModel:model];
    }
}

#pragma mark - <<<<<<<<<<<<<<< 查询数据 >>>>>>>>>>>>>>>
- (NSArray *)selectAllfromTable:(NSString *)tableName
{
    if([self isOpenDB])
    {
        manager.fmrs = [manager.fmdb executeQuery:[NSString stringWithFormat:@"select * from %@", tableName]];
        return [self getArrWithFMResultSet:manager.fmrs table:tableName];
    }
    
    return nil;
    
}

- (NSArray *)selectWithTable:(NSString *)tableName
{
    if([self isOpenDB])
    {
        NSArray *dictArr = [self selectAllfromTable:tableName];
        return [WDDictToModel dictToModelWithModel:tableName andDict:dictArr];
    }
    
    return nil;
}

- (NSArray *)selectWithKeyTypes:(NSDictionary *)keyTypes fromTable:(NSString *)tableName whereCondition:(NSDictionary *)condition
{
    return nil;
}

- (NSArray *)selectWithTable:(NSString *)tableName whereCondition:(NSDictionary *)condition
{
    
    if([self isOpenDB])
    {
        NSString *key = [condition allKeys][0];
        NSString *value = [condition objectForKey:key];
        
        NSString *sql;
        if ([value isKindOfClass:[NSNumber class]]) {
            sql = [NSString stringWithFormat:@"select * from %@ where %@ = %@", tableName,key,value];
        } else {
        
            sql = [NSString stringWithFormat:@"select * from %@ where %@ = '%@'", tableName,key,value];
        }
        
        //WDLog(@"%@", sql);
        manager.fmrs = [manager.fmdb executeQuery:sql];
        
        NSArray *dictArr = [self getArrWithFMResultSet:manager.fmrs table:tableName];
        
        return [WDDictToModel dictToModelWithModel:tableName andDict:dictArr];
    }
    
    return nil;
    
}

#pragma mark - <<<<<<<<<<<<<<< 清空表 >>>>>>>>>>>>>>>
- (void)deleteWithTable:(NSString *)tableName whereCondition:(NSDictionary *)condition
{
    if([self isOpenDB])
    {
        NSString *key = [condition allKeys][0];
        NSString *value = [condition objectForKey:key];
        
        [manager.fmdb executeUpdate:[NSString stringWithFormat:@"delete from %@ where %@ = ?" , tableName, key], value];
    }
}

- (void)clearTable:(NSString *)tableName
{
    if([self isOpenDB])
    {
        [manager.fmdb executeUpdate:[NSString stringWithFormat:@"delete from %@", tableName]];
    }
}

#pragma mark - <<<<<<<<<<<<<<< 公用方法 >>>>>>>>>>>>>>>

-(NSArray *)getArrWithFMResultSet:(FMResultSet *)result table:(NSString *)tableName

{
    
    NSMutableArray *tempArr = [NSMutableArray array];
    
    while ([result next]) {
        
        NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
        
        NSDictionary *keyTypes = [WDDictToModel transformToDictionaryWithModle:tableName];
        
        for (int i = 0; i < keyTypes.count; i++) {
            
            NSString *key = [keyTypes allKeys][i];
            
            NSString *value = [keyTypes valueForKey:key];
            
            if ([value isEqualToString:@"text"]) {
                
                //                字符串
                
                [tempDic setValue:[result stringForColumn:key] forKey:key];
                
            }else if([value isEqualToString:@"blob"])
                
            {
                
                //                二进制对象
                
                [tempDic setValue:[result dataForColumn:key] forKey:key];
                
            }else if ([value isEqualToString:@"integer"])
                
            {
                //                带符号整数类型
                
                [tempDic setValue:[NSNumber numberWithInt:[result intForColumn:key]]forKey:key];
                
            }else if ([value isEqualToString:@"boolean"])
                
            {
                //                BOOL型
                
                [tempDic setValue:[NSNumber numberWithBool:[result boolForColumn:key]] forKey:key];
                
            }else if ([value isEqualToString:@"date"])
                
            {
                
                //                date
                
                [tempDic setValue:[result dateForColumn:key] forKey:key];
            }
            
        }
        
        [tempArr addObject:tempDic];
        
    }
    
    return tempArr;
}

- (NSDictionary *)modelToDictWithModel:(id)model
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    
    NSArray *proArr = [WDDictToModel propertysToArray:NSStringFromClass([model class])];
    
    for(NSString *property in proArr)
    {
        id object = [model valueForKey:property];
        if (object) {
            
            [dict setObject:object forKey:property];
        }
    }
    
    NSDictionary *keyValues = dict;
    
    return keyValues;
}

- (BOOL)isOpenDB
{
    if(![manager.fmdb open])
    {
        manager = nil;
        [[self class] manager];
    }
    
    return YES;
}

@end
